/*
Copyright (C) 2011 The University of Michigan
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Please send inquiries to powertutor@umich.edu
*/
package vn.cybersoft.obs.andriod.batterystats2.components;
import android.content.Context;
import android.media.AudioManager;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.TreeSet;
import vn.cybersoft.obs.andriod.batterystats2.PowerNotifications;
import vn.cybersoft.obs.andriod.batterystats2.service.IterationData;
import vn.cybersoft.obs.andriod.batterystats2.service.PowerData;
import vn.cybersoft.obs.andriod.batterystats2.util.NotificationService;
import vn.cybersoft.obs.andriod.batterystats2.util.Recycler;
/** This class aims to log the audio device status once per log interval */
public class Audio extends PowerComponent {
/** This class is the logger data file corresponding to Audio */
public static class AudioData extends PowerData {
private static Recycler<AudioData> recycler = new Recycler<AudioData>();
public static AudioData obtain() {
AudioData result = recycler.obtain();
if (result != null)
return result;
return new AudioData();
}
@Override
public void recycle() {
recycler.recycle(this);
}
public boolean musicOn;
private AudioData() {
}
public void init(boolean musicOn) {
this.musicOn = musicOn;
}
public void writeLogDataInfo(OutputStreamWriter out) throws IOException {
out.write("Audio-on " + musicOn + "\n");
}
}
private static class MediaData implements Comparable<Object> {
private static Recycler<MediaData> recycler = new Recycler<MediaData>();
public static MediaData obtain() {
MediaData result = recycler.obtain();
if (result != null)
return result;
return new MediaData();
}
public void recycle() {
recycler.recycle(this);
}
public int uid;
public int id;
public int assignUid;
public int compareTo(Object obj) {
MediaData x = (MediaData) obj;
if (uid < x.uid)
return -1;
if (uid > x.uid)
return 1;
if (id < x.id)
return -1;
if (id > x.id)
return 1;
return 0;
}
public boolean equals(Object obj) {
MediaData x = (MediaData) obj;
return uid == x.uid && id == x.id;
}
}
private AudioManager audioManager;
private PowerNotifications audioNotif;
private TreeSet<MediaData> uidData;
public Audio(Context context) {
if (NotificationService.available()) {
uidData = new TreeSet<MediaData>();
audioNotif = new NotificationService.DefaultReceiver() {
private int sysUid = -1;
@Override
public void noteSystemMediaCall(int uid) {
sysUid = uid;
}
@Override
public void noteStartMedia(int uid, int id) {
MediaData data = MediaData.obtain();
data.uid = uid;
data.id = id;
if (uid == 1000 && sysUid != -1) {
data.assignUid = sysUid;
sysUid = -1;
} else {
data.assignUid = uid;
}
synchronized (uidData) {
if (!uidData.add(data)) {
data.recycle();
}
}
}
@Override
public void noteStopMedia(int uid, int id) {
MediaData data = MediaData.obtain();
data.uid = uid;
data.id = id;
synchronized (uidData) {
uidData.remove(data);
}
data.recycle();
}
};
NotificationService.addHook(audioNotif);
}
audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
}
@Override
protected void onExit() {
if (audioNotif != null) {
NotificationService.removeHook(audioNotif);
}
}
@Override
public IterationData calculateIteration(long iteration) {
IterationData result = IterationData.obtain();
AudioData data = AudioData.obtain();
data.init(uidData != null && !uidData.isEmpty()
|| audioManager.isMusicActive());
result.setPowerData(data);
if (uidData != null)
synchronized (uidData) {
int last_uid = -1;
for (MediaData dat : uidData) {
if (dat.uid != last_uid) {
AudioData audioPower = AudioData.obtain();
audioPower.init(true);
result.addUidPowerData(dat.assignUid, audioPower);
}
last_uid = dat.uid;
}
}
return result;
}
@Override
public boolean hasUidInformation() {
return audioNotif != null;
}
@Override
public String getComponentName() {
return "Audio";
}
}